﻿
namespace TFSChangeLog.Operations.Command
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Input;
    using TFSChangeLog.Operations.Services;
    using TFSChangeLog.ViewModel;

    /// <summary>Summary description for <see cref="GenerateReleaseNotesCommand"/> class.</summary>
    public class GenerateReleaseNotesCommand
    {
        #region Fields

        /// <summary>Summary description for class level field of type <c>TFSChangeLog.ViewModel.MainWindowViewModel</c>.</summary>
        private MainWindowViewModel m_ViewModel;

        /// <summary>Gets the value for GenerateReleaseNotes.</summary>
        public ICommand GenerateReleaseNotes { get; private set; }

        #endregion

        #region Constructor

        /// <summary>Initializes a new instance of the <see cref="GenerateReleaseNotesCommand"/> class.</summary>
        /// <param name="viewModel">TODO: Summary description for <c>viewModel</c> parameter of type <c>TFSChangeLog.ViewModel.MainWindowViewModel</c>.</param>
        public GenerateReleaseNotesCommand(MainWindowViewModel viewModel)
        {
            this.m_ViewModel = viewModel;
            this.GenerateCommand();
        }

        /// <summary>Summary description for <c>GenerateReleaseNotesCommand</c> method.</summary>
        private void GenerateCommand()
        {
            this.GenerateReleaseNotes = new RelayCommand(this.OnGenerateReleaseNotes, this.CanGenerateReleaseNotes);
        }

        /// <summary>Summary description for <c>GenerateReleaseNotesCommand</c> method.</summary>
        /// <param name="o">TODO: Summary description for <c>o</c> parameter of type <c>object</c>.</param>
        /// <returns>TODO: returns an object of type <c>bool</c>.</returns>
        private bool CanGenerateReleaseNotes(object o)
        {
            return this.m_ViewModel.CanExecuteGenerateReleaseNotes;
        }

        #endregion

        /// <summary>Summary description for <c>GenerateReleaseNotesCommand</c> method.</summary>
        /// <param name="context">TODO: Summary description for <c>context</c> parameter of type <c>object</c>.</param>
        private void OnGenerateReleaseNotes(object context)
        {
            if (this.m_ViewModel.SelectedFromChangeSet.FromChangesetID > this.m_ViewModel.SelectedToChangeSet.ToChangesetID)
            {
                this.m_ViewModel.RaiseChangeSetSelectionError();
            }
            else
            {
                var progressDialogViewModel = this.m_ViewModel.progressDialogViewModel;
                int[] singleIterationList = { 0 };
                progressDialogViewModel.ResetViewModel();

                progressDialogViewModel.TokenSource = new CancellationTokenSource();

                // Announce that work is starting
                this.m_ViewModel.RaiseGenerateReleaseNotesWorkStartedEvent();
                Task generateReleaseNotesTask =
                    Task.Factory.StartNew(
                        () => GenerateReleaseNotesService.DoWork(
                        singleIterationList, this.m_ViewModel), progressDialogViewModel.TokenSource.Token);

                // Announce that work is ending
                generateReleaseNotesTask.ContinueWith(t => m_ViewModel.RaiseGenerateReleaseNotesWorkEndedEvent(),
                                                      TaskScheduler.FromCurrentSynchronizationContext());
            }
        }
    }
}
